﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace MailSender
{
    public partial class frmSend : Form
    {
        private Mail _mail;
        private frmSend _form;

        public frmSend()
        {
            InitializeComponent();
        }

        private void frmSend_Load(object sender, EventArgs e)
        {
            _form = this;
        }

        private void btnContentFile_Click(object sender, EventArgs e)
        {
            if (ofdFile.ShowDialog() == DialogResult.OK)
            {
                lbContentFile.Text = ofdFile.FileName;
            }
        }

        private void btnSendToFile_Click(object sender, EventArgs e)
        {
            if (ofdFile.ShowDialog() == DialogResult.OK)
            {
                lbAddressFile.Text = ofdFile.FileName;
            }
        }

        private void btnSend_Click(object sendObj, EventArgs e)
        {
            #region 输入检查
            var sendFrom = tbSendFrom.Text.Trim();
            var sender = tbSender.Text.Trim();
            var subject = tbSubject.Text.Trim();
            var contentFile = lbContentFile.Text.Trim();
            var addressFile = lbAddressFile.Text.Trim();

            if (sendFrom == string.Empty)
            {
                MessageBox.Show("请输入发件箱。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            if (sender == string.Empty)
            {
                MessageBox.Show("请输入发件人。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            if (subject == string.Empty)
            {
                MessageBox.Show("请输入邮件标题。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            if (contentFile == string.Empty)
            {
                MessageBox.Show("请选择邮件正文文件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            if (addressFile == string.Empty)
            {
                MessageBox.Show("请选择邮箱列表文件。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }
            #endregion 输入检查

            _mail = new Mail
            {
                SendFrom = sendFrom,
                Sender = sender,
                Subject = subject,
                Content = GetContent(contentFile),
            };

            btnSend.Enabled = false;
            tsPercent.Visible = true;
            tsProgress.Visible = true;

            Thread thread = new Thread(SendMail);
            thread.IsBackground = true;
            thread.Start();
        }

        public void SendMail()
        {
            var addressFile = lbAddressFile.Text.Trim();

            var errorCount = 0;
            var allCount = 0;
            var mailCount = 0;
            var lineCount = GetLineCount(addressFile);

            StreamWriter sw = File.AppendText(AppDomain.CurrentDomain.BaseDirectory + "error.txt");
            sw.WriteLine();
            sw.WriteLine(DateTime.Now.ToString());
            sw.WriteLine("-----------------------------------");
            sw.Flush();

            StreamReader sr = new StreamReader(addressFile);
            while (!sr.EndOfStream)
            {
                allCount++;

                var to = sr.ReadLine();
                if (!string.IsNullOrEmpty(to.Trim()))
                {
                    mailCount++;

                    _mail.SendTo = to;
                    if (_mail.Send() == false)
                    {
                        errorCount++;
                        sw.WriteLine(to);
                    }
                    UpdateText((StatusStrip)_form.Controls.Find("stMain", true)[0], mailCount, errorCount);
                }

                UpdateProgress((StatusStrip)_form.Controls.Find("stMain", true)[0], (int)(((float)allCount / (float)lineCount) * 100));
            }
            sr.Close();
            sw.Flush();
            sw.Close();

            CheckForShutDown((CheckBox)_form.Controls.Find("cbShutdown", true)[0]);
            EnableButton((Button)_form.Controls.Find("btnSend", true)[0], true);
        }

        #region 更新界面的委托方法
        private delegate void UpdateTextDelegate(StatusStrip st, int allCount, int errorCount);
        private delegate void UpdateProgressDelegate(StatusStrip st, int pos);
        private delegate void EnbaleButtonDelegate(Button btn, bool enabled);
        private delegate void CheckForShutDownDelegate(CheckBox cbx);

        public void UpdateText(StatusStrip st, int allCount, int errorCount)
        {
            if (st.InvokeRequired)
            {
                UpdateTextDelegate tbDelegate = new UpdateTextDelegate(UpdateText);
                _form.Invoke(tbDelegate, st, allCount, errorCount);
            }
            else
            {
                var lb = (ToolStripStatusLabel)(st.Items[2]);
                lb.Text = "发送：" + allCount + "个  失败：" + errorCount + "个";
                if (errorCount > 0)
                {
                    lb.ForeColor = Color.Red;
                }
                else
                {
                    lb.ForeColor = Color.Black;
                }
            }
        }

        public void UpdateProgress(StatusStrip st, int pos)
        {
            if (st.InvokeRequired)
            {
                UpdateProgressDelegate pbDelegate = new UpdateProgressDelegate(UpdateProgress);
                _form.Invoke(pbDelegate, st, pos);
            }
            else
            {
                ((ToolStripProgressBar)(st.Items[0])).Value = pos;
                ((ToolStripStatusLabel)(st.Items[1])).Text = pos + "%";
            }
        }

        public void EnableButton(Button btn, bool enabled)
        {
            if (btn.InvokeRequired)
            {
                EnbaleButtonDelegate btnDelegate = new EnbaleButtonDelegate(EnableButton);
                _form.Invoke(btnDelegate, btn, enabled);
            }
            else
            {
                btn.Enabled = enabled;
            }
        }

        public void CheckForShutDown(CheckBox cbx)
        {
            if (cbx.InvokeRequired)
            {
                CheckForShutDownDelegate btnDelegate = new CheckForShutDownDelegate(CheckForShutDown);
                _form.Invoke(btnDelegate, cbx);
            }
            else
            {
                if (cbx.Checked)
                {
                    SystemControl.ShutDown();
                }
                else
                {
                    MessageBox.Show("发送结束！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        #endregion 更新界面的委托方法

        #region 辅助方法
        public long GetLineCount(string filename)
        {
            StreamReader sr = new StreamReader(filename);
            var line = 0L;
            while (sr.ReadLine() != null) line++;
            sr.Close();

            return line;
        }

        public string GetContent(string filename)
        {
            StreamReader sr = new StreamReader(filename);
            var content = sr.ReadToEnd();
            sr.Close();

            return content;
        }
        #endregion 辅助方法

    }

}



